You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

89 lines
2.0 KiB

/**
* GET /api/orders/[id]
*
* Fetch order details by ID
*
* Security:
* - Requires authentication
* - Users can only access their own orders
*
* Response:
* {
* id: string
* orderNumber: string
* totalAmount: string
* status: string
* billingAddress: BillingAddress
* items: OrderItem[]
* createdAt: Date
* }
*/
import { eq, and } from 'drizzle-orm'
import { orders, orderItems } from '../../database/schema'
export default defineEventHandler(async (event) => {
// Require authentication
const { user } = await requireUserSession(event)
// Get order ID from URL parameter
const orderId = getRouterParam(event, 'id')
if (!orderId) {
throw createError({
statusCode: 400,
statusMessage: 'Order ID is required',
})
}
const db = useDatabase()
// Fetch order with items
const order = await db.query.orders.findFirst({
where: and(eq(orders.id, orderId), eq(orders.userId, user.id)),
with: {
items: {
with: {
product: true,
},
},
},
})
if (!order) {
throw createError({
statusCode: 404,
statusMessage: 'Order not found',
})
}
// Transform items to include price and product snapshot data
const transformedItems = order.items.map((item: any) => ({
id: item.id,
orderId: item.orderId,
productId: item.productId,
quantity: item.quantity,
priceSnapshot: item.priceSnapshot,
productSnapshot: item.productSnapshot,
product: {
id: item.product.id,
name: item.product.name,
description: item.product.description,
imageUrl: item.product.imageUrl,
},
subtotal: Number.parseFloat(item.priceSnapshot) * item.quantity,
}))
return {
id: order.id,
orderNumber: order.orderNumber,
totalAmount: order.totalAmount,
status: order.status,
billingAddress: order.billingAddress,
items: transformedItems,
paymentId: order.paymentId,
paymentCompletedAt: order.paymentCompletedAt,
createdAt: order.createdAt,
updatedAt: order.updatedAt,
}
})